/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - geometry/mesh
// Copyright( c) 2015.  All Rights Reserved
//
// File:		AEMeshBuffer.h
// Author:		Gianluca Belardelli
// Date:		07/02/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEMESHBUFFER_H_
#define _AEMESHBUFFER_H_

class AEMeshBuffer;
class AEMeshBufferObject;

typedef AESmartPtr<AEMeshBuffer>		AEMeshBufferPtr;
typedef AESmartPtr<AEMeshBufferObject>	AEMeshBufferObjectPtr;
//typedef VSmartPtr<VisVisibilityObject_cl> VisVisibilityObjectPtr;


/// \brief Enumeratore che definisce come il MeshBuffer
/// memorizza i dati.
enum VMeshBufferStorageMode_e
{
	V_MBSTORAGE_FROMFILE = 0,         ///< Loading from file - let the file format decide
	V_MBSTORAGE_FORCESINGLEBUFFER = 1,///< Use single buffered vertex buffers
	V_MBSTORAGE_FORCEDOUBLEBUFFER = 2 ///< Use double buffered vertex buffers
};


/// \brief Un MeshBuffer consiste in un set di vertici, ed opzionalmente indici, che
/// descrivono una Mesh. I MeshBuffer possono essere utilizzati per renderizzare
/// qualsiasi tipo di geometria custom.
/// Definiscono un Render State che pu&ograve; essere sia uno Shader oppure una singola
/// texture con un valore di trasparenza.

/// A mesh buffer can be rendered via a VisMeshBufferObject_cl instance which keeps position,
/// rotation and render order.
/// 
/// Alternatively mesh buffers can be rendered directly in a render loop inside a
/// VisRenderLoopHelper_cl::BeginMeshRendering() / VisRenderLoopHelper_cl::EndMeshRendering()
/// block.
/// 
/// \sa AEVertexDescriptor
/// \sa VisMeshBufferObject_cl
/// \sa VisRenderLoopHelper_cl::BeginMeshRendering
/// \sa VisRenderLoopHelper_cl::EndMeshRendering
class AEMeshBuffer : public AEResource
{
// Members
private:
	AEBOOL32 	m_bIsFromFile;
	
	// Mesh buffer data
	AEINT32 	m_nCurrentPrimCount;
	AEBOOL32 	m_bMeshDataIsBigEndian;
	AEBOOL32 	m_bVerticesDoubleBuffered;
	AEBOOL32 	m_bIndicesDoubleBuffered;
	AEBOOL32 	m_bDoubleBufferingFromFile; // force double buffering storage mode from file
	
	AEBOOL32 	m_bIsModified;
	AEBOOL32 	m_bVerticesLocked;
	AEBOOL32	m_bIndicesLocked;
	AEBOOL32 	m_bUseProjection;
	
	AEINT8		m_ePrimType; ///< casted to AEPrimitiveType
	
	AEUINT32 	m_nMemUsageFlagVertices;
	AEUINT32 	m_nMemUsageFlagIndices;
	
	//VSimpleRenderState_t m_rsRenderState;
	
	AEINT32 	m_nAllocVertexCount;
	AEINT32 	m_nAllocIndexCount;
	
	AEIndexBufferPtr 	m_spIndexBuffer;
	AEVertexDescriptor 	m_vdVertexDescr;
	
	AEVertexBufferPtr 	m_spVertexBuffer;
	
	AETexturePtr 		m_lpChannelTex[AEMAX_MESHBUFFER_TEXCOORDS];
	
	//VCompiledTechniquePtr m_spDefaultTechnique;
	#if defined(AE_OPENGL) || defined(AE_OPENGLES3)
	AEUINT32			m_uiVAO;
	#endif
private:
	struct AEVertexAttributeEndianInfo
	{
		AEINT16		sOffset;
		AEUINT8		nSize;
		AEUINT8		nCount;
	};
	
	/*friend class Vision;
	friend class VisRenderLoopHelper_cl;
	friend class VisMeshBufferObject_cl;
	friend void SetupVertexBufferTextures(AEMeshBuffer *pBuffer, AEMeshBuffer **pTexStreams, AEINT32 iStreamMask);
	friend void RenderVertexBuffers(const class VisMeshBufferObjectCollection_cl &collection, AEINT32 nMask, VCompiledShaderPass *pCustomShader);
	friend void RenderSingleBufferPrimitives(VisMeshBufferObject_cl *pMeshObj, char primtype, char iTransp, AEMeshBuffer *pIndexBuffer, AEINT32 iFirstPrim, AEINT32 iPrimCount, VCompiledShaderPass *pShader);
	friend void SetupVertexBufferTextureArrays(VisMeshBufferObject_cl *pMeshObj, AEMeshBuffer **pTexStreams);
	//friend char *GetVertexArrayPtr(AEMeshBuffer *pBuffer);
	friend AEINT32 AddMeshBufferStreams(AEMeshBuffer *pMesh, AEINT32 iStreamMasks, AEINT32 iByteOffset, AEINT32 iInstanceCount, AEINT32 iStreamIndex);
	friend void RenderParticleBuffer(VisParticleGroup_cl *pgroup, AEINT32 iParticleCount);
	friend void RenderGeometryParticleBuffer_Instancing(VisParticleGroup_cl *pgroup, AEINT32 iParticleCount);*/
	void VerifyVertexLockedStatus(AEBOOL32 bReqStatus) const;
	void VerifyIndexLockedStatus(AEBOOL32 bReqStatus) const;
	//void UpdateFastCopy( void );
	void Init( void );
	static void InitOneTime( void );
	static void DeInitOneTime( void );
	static AEBOOL32 ConvertFilename(const char *szSrc, char *szDst);
	void platformRender( AEUINT32 nStart, AEUINT32 nEnd );
	//AEINT32 GetAttributeInfo(const AEVertexDescriptor &desc, VertexAttributeEndianInfo_t *pAttributeInfo);
	//void ConvertEndianness(char *pData, AEINT32 iNumVerts, AEINT32 iVertexStride, AEINT32 iNumAttributes, VertexAttributeEndianInfo_t *pAttributeInfo);
	//void ReorderByteAttributes(char *pData, AEINT32 iNumVerts, AEINT32 iVertexStride, AEINT32 iNumAttributes, VertexAttributeEndianInfo_t *pAttributeInfo);
	
	void EnsureBuffersExist( void );

protected:
	// overridden resource functions
	AE_DLLIMPEXP AEBOOL32 Reload( void );
	AE_DLLIMPEXP AEBOOL32 Unload( void );
	AE_DLLIMPEXP void AccumulateMemoryFootprint(size_t &iUniqueSys, size_t &iUniqueGPU, size_t &iDependentSys, size_t &iDependentGPU);

public:
	/** @name Costruttori e distruttore */
	/// @{
	/// \brief Costruttore di default. Non viene allocato niente e la primitiva di
	/// default per questo mesh buffer &egrave; AEPRIMITIVETYPE_TRILIST.
	AE_DLLIMPEXP AEMeshBuffer( void );
	
	/// \brief Costruttore che si occupa di definire il formato dei vertici e degli
	/// indici.
	/// \param vdDescr Referenza ad un oggetto di tipo \b AEVertexDescriptor contenente
	/// il formato dei vertici utilizzato in questo MeshBuffer.
	/// \param nVertexCount Numero di vertici che verranno allocati.
	/// \param ePrimType Tipo di primitiva da utilizzare.
	/// \param nIndexCount Numero di indici che verrano allocati. Pu&ograve; essere
	/// passato anche 0.
	/// \param nPrimCount Numero di primitive da renderizzare. Se il valore passato &egrave;
	/// minore di zero, il numero di primitive verr&agrave; dedotto automaticamente 
	/// dal numero di vertici e indici allocati. Es: per AEPRIMITIVETYPE_TRILIST : num. prim. = nVertexCount/3
	/// \param nUsageFlag Pu&ograve; assumere i valori di \b AEMEMUSAGE_STATIC, \b AEMEMUSAGE_DYNAMIC,
	/// \b AEMEMUSAGE_STREAM e \b AEMEMUSAGE_STATIC_UNMANAGED.<br>
	/// In generale si dovrebbe utilizzare \b AEMEMUSAGE_STATIC per dati che sono specificati una sola
	/// volta e non cambiano mai. \b AEMEMUSAGE_STREAM dovrebbe essere utilizzato per quei dati che vengono
	/// modificati spesso a run-time ma che hanno una frequenza di rendering superiore alla frequenza
	/// di aggiornamento. \b AEMEMUSAGE_DYNAMIC &egrave; la soluzione migliore per quei dati che hanno una
	/// frequenza di rendering e aggiornamento molto simile o uguale.<br>
	/// \b AEMEMUSAGE_STATIC_UNMANAGED &egrave; simile a \b AEMEMUSAGE_STATIC ma consuma meno memoria perch&egrave;
	/// il buffer in memoria di sistema non viene mantenuto automaticamente, ci&ograve; significa
	/// che sar&agrave; necessario gestire manualmente gli eventi di lost device.
	/// \param bDoubleBufferedVertices Specifica se questo MeshBuffer utilizza un vertex buffer
	/// di tipo double-buffered. Il valore di default &egrave AETRUE che significa che i dati
	/// dei vertici saranno replicati nella memoria di sistema. Di conseguenza il puntatore
	/// ritornato dalle operazioni di Lock risiede in memoria di sistema. E' possibile quindi
	/// serializzare e deserializzare i dati dei vertici. Se il double buffering non &egrave;
	/// utilizzato non esiste la copia in memoria di sistema il che significa che sar&agrave;
	/// necessario implementare la gestione della Lost Device.
	/// \param bDoubleBufferedIndices Specifica se gli indici devo essere gestiti con il
	/// double-buffer.. Se il double buffering non &egrave;
	/// utilizzato non esiste la copia in memoria di sistema il che significa che sar&agrave;
	/// necessario implementare la gestione della Lost Device.
	/// \note Utilizzare questo costruttore per inizializzare il buffer. E' comunque possibile
	/// riallocare vertex e index buffer in qualsiasi momento.
	/// \sa AEMeshBuffer::AllocateVertices
	/// \sa AEMeshBuffer::AllocateIndexList
	/// \sa AEMeshBuffer::SetPrimitiveCount
	/// \sa AEMeshBuffer::SetPrimitiveType
	AE_DLLIMPEXP AEMeshBuffer( const AEVertexDescriptor &vdDescr, AEINT32 nVertexCount, 
							AEPrimitiveType ePrimType=AEPRIMITIVETYPE_TRILIST, 
							AEINT32 nIndexCount=0, AEINT32 nPrimCount=-1, 
							AEINT32 nUsageFlag = AEMEMUSAGE_STREAM, 
							AEBOOL32 bDoubleBufferedVertices = AETRUE, 
							AEBOOL32 bDoubleBufferedIndices = AETRUE );
	
	/// \brief Distruttore. Si occupa di rilasciare le risorse allocate.
	AE_DLLIMPEXP virtual ~AEMeshBuffer( void );
	
	/// @}
	/// @name Propriet&agrave; dell'oggetto.
	/// @{
	/// \brief Imposta il tipo di primitiva utilizzato da questo MeshBuffer.
	/// \param ePrimType Il nuovo tipo di primitiva.
	/// \sa AEPrimitiveType
	AE_FORCEINLINE void SetPrimitiveType( AEPrimitiveType ePrimType );
	
	/// \brief Ritorna il tipo di primitiva utilizzato da questo Mesh Buffer.
	/// \return Un valore definito nell'enum AEPrimitiveType che indica il tipo di primitiva.
	/// \sa AEMeshBuffer::SetPrimitiveType
	AE_FORCEINLINE AEPrimitiveType GetPrimitiveType( void ) const;
	
	/// \brief Ritorna il descrittore del formato vertici utilizzato da questo Mesh Buffer.
	/// \param vdDescr Struttura che riceve una copia del descrittore corrente
	/// del formato dei vertici.
	/// \sa AEMeshBuffer::AllocateVertices
	/// \sa AEVertexDescriptor
	AE_FORCEINLINE void GetVertexDescriptor( AEVertexDescriptor &vdDescr ) const;
	
	/// \brief Ritorna la Stream Mask per questo Mesh Buffer.
	/// \return Un valore AEUINT32 contenente la maschera di bit che descrive
	/// lo Stream Mask utilizzato da questo Mesh Buffer. Ogni bit si riferisce
	/// ad un tipo AEVERTEXSTREAM_xxx.
	AE_FORCEINLINE AEUINT32 GetStreamMask( void ) const;
	
	/// @}
	/** @name Allocazione e deallocazione */
	/// @{
	/// \brief Alloca un buffer per i vertici, utilizzando AEVertexDescriptor::m_sStride * nCount
	/// bytes di memoria. E' possibile riallocare in ogni momento un numero differente
	/// di vertici, sar&agrave; cura del metodo liberare la memoria precedentemente
	/// allocata.
	/// \param vdDescr Una referenza di tipo AEVertexDescriptor contenente un descrittore
	/// di vertici valido. Se il descrittore non &egrave; valido sar&agrave; ritornato
	/// un errore.
	/// \param nCount Numero di vertici da allocare.
	/// \param nUsageFlag Pu&ograve; assumere i valori di \b AEMEMUSAGE_STATIC, \b AEMEMUSAGE_DYNAMIC,
	/// \b AEMEMUSAGE_STREAM e \b AEMEMUSAGE_STATIC_UNMANAGED.<br>
	/// In generale si dovrebbe utilizzare \b AEMEMUSAGE_STATIC per dati che sono specificati una sola
	/// volta e non cambiano mai. \b AEMEMUSAGE_STREAM dovrebbe essere utilizzato per quei dati che vengono
	/// modificati spesso a run-time ma che hanno una frequenza di rendering superiore alla frequenza
	/// di aggiornamento. \b AEMEMUSAGE_DYNAMIC &egrave; la soluzione migliore per quei dati che hanno una
	/// frequenza di rendering e aggiornamento molto simile o uguale.<br>
	/// \b AEMEMUSAGE_STATIC_UNMANAGED &egrave; simile a \b AEMEMUSAGE_STATIC ma consuma meno memoria perch&egrave;
	/// il buffer in memoria di sistema non viene mantenuto automaticamente, ci&ograve; significa
	/// che sar&agrave; necessario gestire manualmente gli eventi di lost device.
	/// \param bDoubleBuffered Specifica se questo MeshBuffer utilizza un vertex buffer
	/// di tipo double-buffered. Il valore di default &egrave AETRUE che significa che i dati
	/// dei vertici saranno replicati nella memoria di sistema. Di conseguenza il puntatore
	/// ritornato dalle operazioni di Lock risiede in memoria di sistema. E' possibile quindi
	/// serializzare e deserializzare i dati dei vertici. Se il double buffering non &egrave;
	/// utilizzato non esiste la copia in memoria di sistema il che significa che sar&agrave;
	/// necessario implementare la gestione della Lost Device.
	/// \param nAdditionalBindFlag
	///   \li \b AEBIND_STREAM_OUTPUT: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer come target per le operazioni di Stream Output.
	///   \li \b AEBIND_SHADER_RESOURCE: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer come Shader Resource ( ad esempio per effettuare
	///       accessi in lettura in un Vertex o Pixel shader. Questo flag pu&ograve;
	///       essere utilizzato solo in congiunzione con \b AEMEMUSAGE_STATIC, e non
	///       con \b AEMEMUSAGE_STREAM o \b AEMEMUSAGE_DYNAMIC.
	///   \li \b AEBIND_UNORDERED_ACCESS: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer per il Compute Shader.
	/// \note Non tutte le piattaforme supportano gli nAdditionalBindFlag.
	/// \return \b AETRUE se l'operazione &egrave; andata a buon fine, altrimenti AEFALSE.
	/// \sa AEMeshBuffer::FreeVertices
	/// \sa AEMeshBuffer::AllocateIndexList
	/// \sa AEMeshBuffer::LockVertices
	AE_DLLIMPEXP AEBOOL32 AllocateVertices( const AEVertexDescriptor &vdDescr, AEINT32 nCount, AEINT32 nUsageFlag=AEMEMUSAGE_STATIC, AEBOOL32 bDoubleBuffered = AETRUE, AEINT32 nAdditionalBindFlag = 0 );
	
	/// \brief Rilascia la memoria contenente i vertici.
	AE_DLLIMPEXP void FreeVertices( void );
	
	/// \brief Alloca un buffer per gli indici. Il buffer &egrave; richiesto solo
	/// per primitive di tipo \b AEPRIMITIVETYPE_INDEXED_TRISTRIP, \b AEPRIMITIVETYPE_INDEXED_TRILIST
	/// e \b AEPRIMITIVETYPE_INDEXED_LINELIST, per gli altri tipi gli indici saranno ignorati.
	/// Un singolo indice pu&ograve; essere di 16 o 32 bit dipende dal tipo di buffer. 
	/// E' possibile riallocare in ogni momento un numero differente
	/// di indici, sar&agrave; cura del metodo liberare la memoria precedentemente
	/// allocata.
	/// \param nIndexCount Numero di indici da allocare.
	/// \param nUsageFlag Pu&ograve; assumere i valori di \b AEMEMUSAGE_STATIC, \b AEMEMUSAGE_DYNAMIC,
	/// \b AEMEMUSAGE_STREAM e \b AEMEMUSAGE_STATIC_UNMANAGED.<br>
	/// In generale si dovrebbe utilizzare \b AEMEMUSAGE_STATIC per dati che sono specificati una sola
	/// volta e non cambiano mai. \b AEMEMUSAGE_STREAM dovrebbe essere utilizzato per quei dati che vengono
	/// modificati spesso a run-time ma che hanno una frequenza di rendering superiore alla frequenza
	/// di aggiornamento. \b AEMEMUSAGE_DYNAMIC &egrave; la soluzione migliore per quei dati che hanno una
	/// frequenza di rendering e aggiornamento molto simile o uguale.<br>
	/// \b AEMEMUSAGE_STATIC_UNMANAGED &egrave; simile a \b AEMEMUSAGE_STATIC ma consuma meno memoria perch&egrave;
	/// il buffer in memoria di sistema non viene mantenuto automaticamente, ci&ograve; significa
	/// che sar&agrave; necessario gestire manualmente gli eventi di lost device.
	/// \param eIndexFormat Definisce il formato dell'Index buffer. Utilizzare
	/// \b AEINDEXFORMAT_16 per indici a 16bit oppure \b AEINDEXFORMAT_32 per indici a 32bit.
	/// \param bDoubleBuffered Specifica se questo MeshBuffer utilizza un index buffer
	/// di tipo double-buffered. Il valore di default &egrave \b AETRUE che significa che i dati
	/// degli indici saranno replicati nella memoria di sistema. Di conseguenza il puntatore
	/// ritornato dalle operazioni di Lock risiede in memoria di sistema. E' possibile quindi
	/// serializzare e deserializzare i dati dei vertici. Se il double buffering non &egrave;
	/// utilizzato non esiste la copia in memoria di sistema il che significa che sar&agrave;
	/// necessario implementare la gestione della Lost Device.
	/// \param nAdditionalBindFlag
	///   \li \b AEBIND_STREAM_OUTPUT: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer come target per le operazioni di Stream Output.
	///   \li \b AEBIND_SHADER_RESOURCE: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer come Shader Resource ( ad esempio per effettuare
	///       accessi in lettura in un Vertex o Pixel shader. Questo flag pu&ograve;
	///       essere utilizzato solo in congiunzione con \b AEMEMUSAGE_STATIC, e non
	///       con \b AEMEMUSAGE_STREAM o \b AEMEMUSAGE_DYNAMIC.
	///   \li \b AEBIND_UNORDERED_ACCESS: Specificando questo valore sar&agrave; possibile
	///       utilizzare questo buffer per il Compute Shader.
	/// \note Non tutte le piattaforme supportano gli nAdditionalBindFlag.
	/// \return AETRUE se l'operazione &egrave; andata a buon fine, altrimenti AEFALSE.	/// 
	/// \sa AEMeshBuffer::FreeIndexList
	/// \sa AEMeshBuffer::AllocateVertices
	/// \sa AEMeshBuffer::LockIndices
	AE_DLLIMPEXP AEBOOL32 AllocateIndexList( AEINT32 nIndexCount, AEINT32 nUsageFlag=AEMEMUSAGE_STATIC, AEIndexFormat eIndexFormat = AEINDEXFORMAT_16, AEBOOL32 bDoubleBuffered = AETRUE, AEINT32 nAdditionalBindFlag = 0 );
	
	/// \brief Rilascia la memoria utilizzata dagli Indici.
	AE_DLLIMPEXP void FreeIndexList( void );
	
	/// \brief Ritorna il tipo di utilizzo di memoria utilizzato dal VertexBuffer.
	/// \return Uno tra i valori: AEMEMUSAGE_STATIC, AEMEMUSAGE_DYNAMIC, AEMEMUSAGE_STREAM, AEMEMUSAGE_STATIC_UNMANAGED
	AE_FORCEINLINE AEUINT32 GetVertexUsageFlags( void ) const;
	
	/// \brief Ritorna il tipo di utilizzo di memoria utilizzato dall'IndexBuffer.
	/// \return Uno tra i valori: AEMEMUSAGE_STATIC, AEMEMUSAGE_DYNAMIC, AEMEMUSAGE_STREAM, AEMEMUSAGE_STATIC_UNMANAGED
	AE_FORCEINLINE AEUINT32 GetIndexUsageFlags( void ) const;
	
	/// \brief Ritorna se i vertici e gli indici sono a singolo o doppio buffer.
	/// \param bVerticesDoubleBuffered [out] AETRUE per vertici doublebuffered altrimenti AEFALSE.
	/// \param bIndicesDoubleBuffered [out] AETRUE per indici doublebuffered altrimenti AEFALSE.
	/// \param bDoubleBufferingFromFile [out] Se il valore &egrave; \b AETRUE l'utilizzo del
	/// doppio buffer &egrave; pilotato direttamente dalle informazioni presenti nel file .aemesh
	/// ignorando ogni modifica globale.
	AE_FORCEINLINE void GetDoubleBuffering( AEBOOL32 &bVerticesDoubleBuffered, AEBOOL32 &bIndicesDoubleBuffered, AEBOOL32 &bDoubleBufferingFromFile ) const;
	
	/// \brief
	///   Sets whether vertices/ indices should be single or double buffered.
	/// 
	/// \param bVerticesDoubleBuffered
	///   Storage mode for vertices.
	/// 
	/// \param bIndicesDoubleBuffered
	///   Storage mode for indices.
	/// 
	/// \param bDoubleBufferingFromFile 
	///   If value is set to AETRUE storage modes will be always determined from corresponding mesh file, global settings will be ignored.
	///   Otherwise storage modes will be overwritten by global settings.
	AE_FORCEINLINE void SetDoubleBuffering( AEBOOL32 bVerticesDoubleBuffered, AEBOOL32 bIndicesDoubleBuffered, AEBOOL32 bDoubleBufferingFromFile );
	
	/// @}
	/** @name Conteggio Vertici/Indici/Primitive */
	/// @{
	/// \brief Imposta il numero di primitive da renderizzare che per
	/// default &egrave; il massimo consentito dal tipo di primitiva e
	/// il numero di vertici/indici allocati.
	/// \param nNewCount Numero di primitive da renderizzare, non deve superare
	/// il numero massimo consentito. Se il valore &egrave; -1 renderizza sempre
	/// il numero massimo consentito.
	/// \return \b AETRUE se il numero di primitive &egrave; valido, altrimenti \b AEFALSE.
	/// \note Il numero di primitive &egrave; passato al metodo OnRender e pu&ograve;
	/// comunque essere cambiato.
	/// \note Il numero massimo di primitive &egrave; calcolato nel seguente modo:
	///   \li per \b AEPRIMITIVETYPE_TRILIST:  max count = numVertices / 3,
	///   \li per \b AEPRIMITIVETYPE_TRISTRIP: max count = numVertices - 2,
	///   \li per \b AEPRIMITIVETYPE_INDEXED_TRILIST:  max count = numIndices / 3,
	///   \li per \b AEPRIMITIVETYPE_INDEXED_TRISTRIP: max count = numIndices - 2,
	///   \li per \b AEPRIMITIVETYPE_LINELIST: max count = numVertices / 2
	///   \li per \b AEPRIMITIVETYPE_INDEXED_LINELIST: max count = numIndices / 2
	///   \li per \b AEPRIMITIVETYPE_POINTLIST: max count = numVertices
	/// \sa AEMeshBufferObject::OnRender
	/// \sa AEMeshBuffer::GetCurrentPrimitiveCount
	AE_DLLIMPEXP AEBOOL32 SetPrimitiveCount( AEINT32 nNewCount = -1 );
	
	/// \brief Ritorna il numero di primitive.
	/// \sa AEMeshBufferObject::OnRender
	/// \sa AEMeshBuffer::SetCurrentPrimitiveCount
	AE_DLLIMPEXP AEINT32 GetCurrentPrimitiveCount( void ) const;
	
	/// \brief Ritorna il numero di vertici allocati.
	/// \return Valore \b AEINT32 contenente il numero di vertici allocati.
	AE_FORCEINLINE AEINT32 GetVertexCount( void ) const;
	
	/// \brief Ritorna il numero di indici allocati.
	/// \return Valore \b AEINT32 contenente il numero di indici allocati.
	AE_FORCEINLINE AEINT32 GetIndexCount( void ) const;
	
	/// @}
	/** @name Funzionalit&agrave; Lock e Unlock */
	/// @{
	/// \brief Ritorna \b AETRUE se il MeshBuffer pu&ograve; essere Lockato in lettura.
	/// \return \b AETRUE se il buffer &egrave; lockabile in lettura, altrimenti \b AEFALSE.
	AE_FORCEINLINE AEBOOL32 CanBeLockedForReading( void ) const;
	
	/// \brief Esegue un Lock sul VertexBuffer per avere l'accesso in scrittura ad esso.
	/// Il metodo ritorna un puntatore che pu&ograve; essere 'castato' nel formato vertici
	/// specificato dalla struttura AEVertexDescriptor. Il buffer ritornato pu&ograve;
	/// essere modificato fino a che non viene eseguita l'operazione di Unlock.
	/// Effettuare un Lock parziale dei dati pu&ograve; incrementare le prestazioni
	/// dal momento che solo una parte del buffer deve essere copiata.
	/// \note Effettuare un'operazione di rendering su un buffer Lockato causa errori
	/// fatali.
	/// \note Non salvare il puntatore ritornato perch&egrave; dopo l'operazione di
	/// Unlock potrebbe non essere pi&ugrave; valido.
	/// \param nFlags Flag che specificano il tipo di lock desiderato.
	/// I valori possibili sono:
	///   \li \b AELOCKFLAG_DISCARDABLE: Specificare questo flag se \b tutti i dati presenti nell'area
	///        di memoria devono essere sovrascritti. Questo permette di rimpiazzare tutti i dati interni
	///        con una nuova area di memoria. In questo modo si evita di attendere che la GPU finisca di
	///        utilizzare questa risorsa. La memoria correntemente utilizzata dalla GPU sar&agrave; rilasciata
	///        non appena avr&agrave; finito di utilizzarla e rimpiazzata con quella appena creata.
	///   \li \b AELOCKFLAG_READONLY: Specificare questo flag se non c'&egrave; la necessit&agrave; di
	///        scrivere i dati in memoria. Questo permette di non eseguire l'upload dei dati sulla GPU.
	///   \li \b AELOCKFLAG_NOOVERWRITE: Specificare questo flag se &egrave; garantito che l'area di memoria
	///        lockata non &egrave attualmente in uso dalla GPU. Questo permette un'accesso diretto alla
	///        memoria evitando cos&igrave; le attese di utilizzo da parte della GPU.
	/// \param nFirst Indice del primo vetice da Lockare. Se non &egrave; specificato
	/// l'indice parte dal primo vertice.
	/// \param nCount Numero di vertici da Lockare. Se non &egrave; specificato tutti i
	/// vertici a partire da quello indicato nel parametro \i nFirst saranno Lockati.
	/// \return Puntatore al vertex buffer o AENULL se l'operazione non &egrave; andata
	/// a buon fine.
	/// \sa AEMeshBuffer::UnLockVertices
	/// \sa AEMeshBuffer::LockIndices
	AE_DLLIMPEXP void *LockVertices( AEINT32 nFlags, AEINT32 nFirst=0, AEINT32 nCount=-1 );
	
	/// \brief Esegue l'Unlock sul VertexBuffer committando in memoria
	/// i dati modificati.
	/// \sa AEMeshBuffer::LockVertices
	AE_DLLIMPEXP void UnLockVertices( void );
	
	/// \brief Esegue un Lock sull'IndexBuffer per avere l'accesso in scrittura ad esso.
	/// Il metodo ritorna sempre un puntatore a valori unsigned short.
	/// Ogni indice referenzia un vertice all'interno del VertexBuffer (0-based).
	/// Il buffer pu&ograve; essere modificato fino a che si trova nello stato Locked,
	/// eseguire l'Unlock subito dopo aver finito di scrivere sul buffer.
	/// \param nFlags Flag che specificano il tipo di lock desiderato.
	/// I valori possibili sono:
	///   \li \b AELOCKFLAG_DISCARDABLE: Specificare questo flag se \b tutti i dati presenti nell'area
	///        di memoria devono essere sovrascritti. Questo permette di rimpiazzare tutti i dati interni
	///        con una nuova area di memoria. In questo modo si evita di attendere che la GPU finisca di
	///        utilizzare questa risorsa. La memoria correntemente utilizzata dalla GPU sar&agrave; rilasciata
	///        non appena avr&agrave; finito di utilizzarla e rimpiazzata con quella appena creata.
	///   \li \b AELOCKFLAG_READONLY: Specificare questo flag se non c'&egrave; la necessit&agrave; di
	///        scrivere i dati in memoria. Questo permette di non eseguire l'upload dei dati sulla GPU.
	///   \li \b AELOCKFLAG_NOOVERWRITE: Specificare questo flag se &egrave; garantito che l'area di memoria
	///        lockata non &egrave attualmente in uso dalla GPU. Questo permette un'accesso diretto alla
	///        memoria evitando cos&igrave; le attese di utilizzo da parte della GPU.
	/// \param nFirst Indica il primo indice da cui far partire il Lock.
	/// \param nCount Numero di indici da Lockare. Un valore di -1 significa tutto il resto
	/// del buffer a partire da nFirst.
	/// \return Se gli indici sono stati precedentemente allocati il valore di ritorno
	/// sar&agrave; un puntatore valido all'interno dell'IndexBuffer altrimenti sar&agrave;
	/// ritornato \b AENULL.
	/// \sa AEMeshBuffer::UnLockIndices
	/// \sa AEMeshBuffer::LockVertices
	AE_DLLIMPEXP void *LockIndices( AEINT32 nFlags, AEINT32 nFirst=0, AEINT32 nCount=-1 );
	
	/// \brief Esegue l'Unlock sull'IndexBuffer committando in memoria
	/// i dati modificati.
	/// \sa AEMeshBuffer::LockIndices
	/// \sa AEMeshBuffer::UnLockVertices
	AE_DLLIMPEXP void UnLockIndices( void );
	
	/// \brief Riempie il VertexBuffer con dati custom.
	/// \param lpSourceData Puntatore ai dati che saranno inseriti nel VertexBuffer.
	/// \param nMemSize Numero di bytes da aggiornare.
	/// \param bNoOverwrite Se \b AETRUE l'applicazione non sovrascrive i dati che sono
	/// attualmente in uso dalla GPU. Impostare propriamente questo flag a \b AETRUE
	/// pu&ograve; migliorare le prestazioni su alcune piattaforme.
	AE_DLLIMPEXP void FillVerticesWithData( const void *lpSourceData, AEINT32 nMemSize, AEBOOL32 bNoOverwrite = AEFALSE );
	
	/// \brief Riempie l'IndexBuffer con dati custom.
	/// \param lpSourceData Puntatore ai dati che saranno inseriti nell'IndexBuffer.
	/// \param nMemSize Numero di bytes da aggiornare.
	/// \param bNoOverwrite Se \b AETRUE l'applicazione non sovrascrive i dati che sono
	/// attualmente in uso dalla GPU. Impostare propriamente questo flag a \b AETRUE
	/// pu&ograve; migliorare le prestazioni su alcune piattaforme.
	AE_DLLIMPEXP void FillIndicesWithData( const void *lpSourceData, AEINT32 nMemSize, AEBOOL32 bNoOverwrite = AEFALSE );
	
	/// \brief Ritorna lo stato Lock/Unlock del VertexBuffer.
	/// \return AETRUE se il VertexBuffer &egrave; Locked altrimenti AEFALSE.
	AE_FORCEINLINE AEBOOL32 AreVerticesLocked( void ) const;
	
	/// \brief Ritorna lo stato Lock/Unlock dell'IndexBuffer.
	/// \return AETRUE se l'IndexBuffer &egrave; Locked altrimenti AEFALSE.
	AE_FORCEINLINE AEBOOL32 AreIndicesLocked( void ) const;
	
	/// @}
	/** @name Default Render State */
	/// @{
	/// \brief
	///   Sets the base texture of the buffer
	/// 
	/// The base texture is used for textured vertex buffers (for all stages, if no shaders are
	/// applied)
	/// 
	/// It is also referred as "BaseTexture" when applying shader.
	/// 
	/// Use the SetChannelTexture function to set the texture for a specific sampler stage.
	/// 
	/// Setting the base texture will overwrite all MAX_MESHBUFFER_TEXCOORDS channel textures with
	/// this texture.
	/// 
	/// This version takes a Vision texture object directly.
	/// 
	/// \param pTextureObject
	///   the texture object to use as base texture
	/// 
	/// \sa AEMeshBuffer::GetBaseTexture
	/// \sa AEMeshBuffer::SetChannelTexture
	AE_FORCEINLINE void SetBaseTexture( AETexture *lpTextureObject );
	
	/// \brief
	///   Sets the base texture of the buffer
	/// 
	/// The base texture is used for textured vertex buffers (for all stages, if no shaders are
	/// applied)
	/// 
	/// It is also referred as "BaseTexture" when applying shader
	/// 
	/// Use the SetChannelTexture function to set the texture for a specific sampler stage.
	/// 
	/// Setting the base texture will overwrite all MAX_MESHBUFFER_TEXCOORDS channel textures with
	/// this texture
	/// 
	/// \param lpFilename
	///   filename of the texture to load
	/// 
	/// \return
	///   AETexture* pTexture : pointer to Vision texture object, if loading was successful,
	///   NULL otherwise
	/// 
	/// \sa AEMeshBuffer::GetBaseTexture
	/// \sa AEMeshBuffer::SetChannelTexture
	AE_DLLIMPEXP AETexture *SetBaseTexture( const char *lpFilename );
	
	/// \brief
	///   Returns the Vision texture object of the current base texture.
	/// 
	/// If no base texture has been specified, it returns NULL.
	/// 
	/// This function wraps around GetChannelTexture(0).
	/// 
	/// \return
	///   AETexture* pTexture : pointer to the texture object
	/// 
	/// \sa AEMeshBuffer::SetBaseTexture
	/// \sa AEMeshBuffer::SetChannelTexture
	AE_FORCEINLINE AETexture *GetBaseTexture( void ) const;
	
	/// \brief
	///   Sets the texture object for a specific texture sampler stage
	/// 
	/// It is referred as "BaseTexture" for the respective sampler stage when applying shader.
	/// 
	/// This version takes a Vision texture object directly.
	/// 
	/// \param pTextureObject
	///   the texture object to use
	/// 
	/// \param nChannel
	///   The channel number, must be in valid range of [0..MAX_MESHBUFFER_TEXCOORDS-1] (maximum
	///   number of  supported channels for Vision mesh buffers, currently 8)
	/// 
	/// \sa AEMeshBuffer::SetBaseTexture
	/// \sa AEMeshBuffer::GetChannelTexture
	AE_FORCEINLINE void SetChannelTexture( AETexture *lpTextureObject, AEINT32 nChannel );
	
	/// \brief
	///   Loads a texture file and sets the texture for a specific texture sampler stage.
	/// 
	/// It is referred as "BaseTexture" for the respective sampler stage when applying shader.
	/// 
	/// This version takes a Vision texture object directly.
	/// 
	/// \param lpFilename
	///   filename of the texture to load
	/// 
	/// \param nChannel
	///   The channel number, must be in valid range of [0..MAX_MESHBUFFER_TEXCOORDS-1] (maximum
	///   number of  supported channels for Vision mesh buffers, currently 8)
	/// 
	/// \return
	///   AETexture* pTexture : pointer to the texture object, if loading was successful, NULL
	///   otherwise
	/// 
	/// \sa AEMeshBuffer::SetBaseTexture
	/// \sa AEMeshBuffer::GetChannelTexture
	AE_DLLIMPEXP AETexture *SetChannelTexture( const char *lpFilename, AEINT32 nChannel );
	
	/// \brief
	///   Returns the texture object for a specific texture sampler stage
	/// 
	/// \param nChannel
	///   The channel number, must be in valid range of [0..MAX_MESHBUFFER_TEXCOORDS-1]
	/// 
	/// \return
	///   AETexture* pTexture : pointer to Vision texture object of the respective channel
	/// 
	/// \sa AEMeshBuffer::SetChannelTexture
	/// \sa AEMeshBuffer::SetBaseTexture
	/// \sa AEMeshBuffer::GetBaseTexture
	AE_FORCEINLINE AETexture *GetChannelTexture( AEINT32 nChannel ) const;
	
	
	/// \brief
	///   Sets the default transparency for rendering (if no shaders are applied)
	/// 
	/// Any shader effect applied to the mesh buffer or the mesh buffer object will supersede this
	/// mode, unless it uses the "blending from surface" flag.
	/// 
	/// \param eTransp
	///   transparency type to use
	/// 
	/// \sa AEMeshBuffer::GetDefaultTransparency
	/// \sa AETransparencyType
	AE_FORCEINLINE void SetDefaultTransparency( AETransparencyType eTransp );
	
	/// \brief Ritorna la tipologia di trasparenza utilizzata.
	/// \return
	///   AETransparencyType eType: transparency type
	/// \sa AEMeshBuffer::GetDefaultTransparency
	/// \sa AETransparencyType
	AE_FORCEINLINE AETransparencyType GetDefaultTransparency( void ) const;
	
	/// \brief
	///   Sets the default flag for writing to z-buffer (if no shaders are applied)
	/// 
	/// the default status is AETRUE.
	/// 
	/// Any shader effect applied to the mesh buffer or the mesh buffer object will supersede this
	/// flag
	/// 
	/// \param bStatus
	///   New status. If AETRUE, the geometry will write to the z-buffer.
	/// 
	/// \sa AEMeshBuffer::IsDefaultZBufferWritingEnabled
	/// \sa AEMeshBuffer::GetDefaultTransparency
	/// \sa AEMeshBuffer::SetDefaultTransparency
	AE_FORCEINLINE void EnableDefaultZBufferWriting( AEBOOL32 bStatus );
	
	/// \brief
	///   Returns the default flag for writing to z-buffer set by EnableDefaultZBufferWriting
	/// 
	/// \return
	///   AEBOOL32 bStatus : The current z-buffer writing status
	/// 
	/// \sa AEMeshBuffer::EnableDefaultZBufferWriting
	/// \sa AEMeshBuffer::GetDefaultTransparency
	/// \sa AEMeshBuffer::SetDefaultTransparency
	AE_FORCEINLINE AEBOOL32 IsDefaultZBufferWritingEnabled( void ) const;
	
	/// \brief
	///   Sets the default face culling mode for this mesh buffer (if no shaders are applied)
	/// 
	/// The default status is culling back faces (CULL_BACK).
	/// 
	/// Any shader effect applied to the mesh buffer or the mesh buffer object will supersede this
	/// mode.
	/// 
	/// To render the mesh buffer double-sided, use the CULL_NONE mode.
	/// 
	/// \param eCullMode
	///   New face culling mode. Supported values are CULL_NONE, CULL_FRONT, and CULL_BACK.
	/// 
	/// \sa AEMeshBuffer::GetDefaultCullMode
	/// \sa AEMeshBuffer::SetDefaultTechnique
	/// \sa VisMeshBufferObject_cl::SetTechnique
	AE_FORCEINLINE void SetDefaultCullMode( AECullMode eCullMode=AECULLMODE_BACK );
	
	/// \brief
	///   Returns the current default face culling mode
	/// 
	/// This mode is set by SetDefaultCullMode.
	/// 
	/// \return
	///   AECullMode eCullMode : The current culling mode
	/// 
	/// \sa AEMeshBuffer::SetDefaultFaceCullMode
	/// \sa AEMeshBuffer::SetDefaultTechnique
	/// \sa VisMeshBufferObject_cl::SetTechnique
	AE_FORCEINLINE AECullMode GetDefaultCullMode( void ) const;
	
	/// \brief
	///   Sets the default render state flags. The passed value encodes transparency type, z-buffer
	///   writing, culling, fog.
	/// 
	/// The passed value encodes transparency type, z-buffer writing, culling, fog.
	/// 
	/// Setting a new value overwrites the flags set by any of the functions SetDefaultTransparency,
	/// EnableDefaultZBufferWriting, and SetDefaultCullMode.
	/// 
	/// In addition, the bitflags for alpha test (RENDERSTATEFLAG_ALPHATEST) and
	/// RENDERSTATEFLAG_ALWAYSVISIBLE to ignore the z-buffer can be set.
	/// 
	/// All flags are only considered for fixed function rendering. Any shader effect applied either
	/// to the mesh buffer or the mesh buffer object will supersede these flags.
	/// 
	/// \param state
	///   The new state constants
	//AE_FORCEINLINE void SetDefaultRenderState( const VSimpleRenderState_t &state );
	
	/// \brief
	///   Returns the state set via SetDefaultRenderState
	//AE_FORCEINLINE VSimpleRenderState_t GetDefaultRenderState() const;
	
	/// \brief
	///   Sets the default shader technique for this mesh buffer.
	/// 
	/// Setting a shader technique in the VisMeshBufferObject_cl object will supersede this default
	/// technique.
	/// 
	/// \param pTechnique
	///   The new default technique, or NULL if no default technique should be used
	/*AE_FORCEINLINE void SetDefaultTechnique(VCompiledTechnique *pTechnique);
	
	/// \brief
	///   Returns the default shader technique for this mesh buffer.
	/// 
	/// \return
	///   VCompiledTechnique *pTechnique: The default technique, or NULL if no default technique is
	///   in use for this mesh buffer
	AE_FORCEINLINE VCompiledTechnique *GetDefaultTechnique() const;
	*/	
	
	///
	/// @}
	///
	
	///
	/// @name Projection
	/// @{
	///
	
	
	/// \brief
	///   Sets the status of using the projection matrix for rendering.
	/// 
	/// The default status is enabled, which means the mesh buffer is rendered as usual geometry in
	/// the scene.
	/// 
	/// When disabled, the mesh buffer is rendered screen aligned, which might be useful for GUI
	/// related rendering.
	/// 
	/// When disabled, the coordinate system for all vertex position coordinates ranges from -1 to 1.
	/// (0,0,0) means screen center, x=-1, y=1 means upper left screen corner. z=-1 specifies the
	/// distance of the near clip plane, z=1 is the far clip plane.
	/// 
	/// When disabled, the positioning and rotation of the referencing mesh buffer object is ignored.
	/// 
	/// \param bStatus
	///   The new status for using the projection matrix
	/// 
	/// \sa AEMeshBuffer::GetUseProjectionMatrix
	AE_FORCEINLINE void SetUseProjectionMatrix( AEBOOL32 bStatus );
	
	
	/// \brief
	///   Retrieves the current status of using the projection matrix for rendering.
	/// 
	/// \return
	///   AEBOOL32 bStatus: The current status for using the projection matrix
	/// 
	/// \sa AEMeshBuffer::SetUseProjectionMatrix
	AE_FORCEINLINE AEBOOL32 GetUseProjectionMatrix( void ) const;
	
	
	///
	/// @}
	///
	
	///
	/// @name Tracing
	/// @{
	///
	
	
	/// \brief
	///   Fills in a collision mesh structure using this mesh buffer or parts of it
	/// 
	/// This function handles all primitive types properly.
	/// 
	/// Use this function only for 16 bit index buffers; for 32 bit index buffers, use
	/// CreateCollisionMesh32 instead.
	/// 
	/// \param pDestMesh
	///   The destination collision mesh that will be filled with mesh information.
	/// 
	/// \param iFirstPrimitive
	///   The first primitive in the collision mesh to start with.
	/// 
	/// \param iPrimitiveCount
	///   The number of primitives to copy starting at iFirstPrimitive. Can be -1 to use all
	///   remaining.
	/// 
	/// \param bFlipFaces
	///   Specify this flag to flip each face
	/// 
	/// \return
	///   AEBOOL32 bStatus: AETRUE if successful
	//AE_DLLIMPEXP AEBOOL32 CreateCollisionMesh(VSimpleCollisionMesh *pDestMesh, AEINT32 iFirstPrimitive=0, AEINT32 iPrimitiveCount=-1, AEBOOL32 bFlipFaces=AEFALSE);
	
	/// \brief
	///   Fills in a collision mesh structure using this mesh buffer or parts of it
	/// 
	/// This function handles all primitive types properly.
	/// 
	/// Use this function only for 32 bit index buffers; for 16 bit index buffers, use
	/// CreateCollisionMesh instead.
	/// 
	/// \param pDestMesh
	///   The destination collision mesh that will be filled with mesh information.
	/// 
	/// \param iFirstPrimitive
	///   The first primitive in the collision mesh to start with.
	/// 
	/// \param iPrimitiveCount
	///   The number of primitives to copy starting at iFirstPrimitive. Can be -1 to use all
	///   remaining.
	/// 
	/// \param bFlipFaces
	///   Specify this flag to flip each face
	/// 
	/// \return
	///   AEBOOL32 bStatus: AETRUE if successful
	//AE_DLLIMPEXP AEBOOL32 CreateCollisionMesh32(VSimpleCollisionMesh32 *pDestMesh, AEINT32 iFirstPrimitive, AEINT32 iPrimitiveCount, AEBOOL32 bFlipFaces=AEFALSE);
	
	
	///
	/// @}
	/** @name Replacing Vertex and Index Buffers */
	/// @{
	/// \brief
	///   Replaces a mesh buffer's vertex buffer
	/// 
	/// The passed vertex buffer object can either be a single-buffered or double-buffered vertex
	/// buffer. Both types are supported.
	/// 
	/// The previously set vertex buffer will have its reference count decreased and may, depending
	/// on further references, be physically deleted.
	/// 
	/// \param pVertexBuffer
	///   The new vertex buffer.
	/// 
	/// \param descr
	///   The vertex descriptor for the vertices in the vertex buffer.
	/// 
	/// \param nCount
	///   The number of vertices in the vertex buffer.
	/// 
	/// \param nUsageFlag
	///   Can either be VIS_MEMUSAGE_STATIC, VIS_MEMUSAGE_STATIC_UNMANAGED, AEMEMUSAGE_STREAM, or
	///   VIS_MEMUSAGE_DYNAMIC. In general, you should use STATIC for vertex data that is specified
	///   only once and then never changed. STREAM should be used for vertex data that is modified or
	///   re-specified in run-time, but used for rendering more often than it is updated. DYNAMIC is
	///   the best solution for data that has about a 1:1 update to render ratio. The difference
	///   between VIS_MEMUSAGE_STATIC and VIS_MEMUSAGE_STATIC_UNMANAGED is that an unmanaged buffer
	///   will never be double-buffered by the graphics API. It may therefore consume less memory on
	///   some platforms with separate memory pools, but you will have to take care of lost device
	///   handling etc. yourself. It is generally recommended NOT to use
	///   VIS_MEMUSAGE_STATIC_UNMANAGED.
	///   In addition to one of these basic settings (which can't be combined), you can specify 
	///   VIS_MEMUSAGE_UAV_BYTEADDRESS or VIS_MEMUSAGE_STRUCTURED to determine the way this buffer
	///   is addressed when using it as an unordered access resource in a compute shader DX11.
	///
	/// \param nAdditionalBindFlag
	///   In DX10/DX11 you can specify additional bind flags as follows:
	///   \li VIS_BIND_STREAM_OUTPUT: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as a target for stream output operations.
	///   \li VIS_BIND_SHADER_RESOURCE: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as a shader resource (e.g. in order to perform random-access reads from the
	///       buffer in a vertex or pixel shader). This can only be used in conjunction with VIS_MEMUSAGE_STATIC, not
	///       with AEMEMUSAGE_STREAM or VIS_MEMUSAGE_DYNAMIC.
	///   \li VIS_BIND_UNORDERED_ACCESS: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as an unordered access resource for compute shaders.
	/// 
	/// \sa AEMeshBuffer::SetIndexBuffer
	AE_DLLIMPEXP void SetVertexBuffer( AEVertexBuffer *lpVertexBuffer, const AEVertexDescriptor &vdDescr, AEINT32 nCount, AEINT32 nUsageFlag, AEINT32 nAdditionalBindFlag );
	
	/// \brief Ritorna il VertexBuffer della Mesh.
	/// \return Un oggetto di tipo AEVertexBuffer contenente il VertexBuffer.
	AE_FORCEINLINE AEVertexBuffer *GetVertexBuffer( void );
	
	/// \brief
	///   Replaces a mesh buffer's index buffer
	/// 
	/// The previously set index buffer will have its reference count decreased and may, depending on
	/// further references, be physically deleted.
	/// 
	/// The index data in the passed index buffer is expected to be 16 Bits per index.
	/// 
	/// \param pIndexBuffer
	///   The new index buffer.
	/// 
	/// \param nIndexCount
	///   The number of indices in the index buffer.
	/// 
	/// \param nUsageFlag
	///   Can either be VIS_MEMUSAGE_STATIC, VIS_MEMUSAGE_STATIC_UNMANAGED, AEMEMUSAGE_STREAM, or
	///   VIS_MEMUSAGE_DYNAMIC. In general, you should use STATIC for vertex data that is specified
	///   only once and then never changed. STREAM should be used for vertex data that is modified or
	///   re-specified in run-time, but used for rendering more often than it is updated. DYNAMIC is
	///   the best solution for data that has about a 1:1 update to render ratio. The difference
	///   between VIS_MEMUSAGE_STATIC and VIS_MEMUSAGE_STATIC_UNMANAGED is that an unmanaged buffer
	///   will never be double-buffered by the graphics API. It may therefore consume less memory on
	///   some platforms with separate memory pools, but you will have to take care of lost device
	///   handling etc. yourself. It is generally recommended NOT to use
	///   VIS_MEMUSAGE_STATIC_UNMANAGED.
	///   In addition to one of these basic settings (which can't be combined), you can specify 
	///   VIS_MEMUSAGE_UAV_BYTEADDRESS or VIS_MEMUSAGE_STRUCTURED to determine the way this buffer
	///   is addressed when using it as an unordered access resource in a compute shader DX11.
	///
	/// \param nAdditionalBindFlag
	///   In DX10/DX11 you can specify additional bind flags as follows:
	///   \li VIS_BIND_STREAM_OUTPUT: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as a target for stream output operations.
	///   \li VIS_BIND_SHADER_RESOURCE: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as a shader resource (e.g. in order to perform random-access reads from the
	///       buffer in a vertex or pixel shader). This can only be used in conjunction with VIS_MEMUSAGE_STATIC, not
	///       with AEMEMUSAGE_STREAM or VIS_MEMUSAGE_DYNAMIC.
	///   \li VIS_BIND_UNORDERED_ACCESS: In DX10/DX11, specifying this value will allow you to use
	///       this buffer as an unordered access resource for compute shaders.
	/// 
	/// \sa AEMeshBuffer::SetIndexBuffer
	AE_DLLIMPEXP void SetIndexBuffer( AEIndexBuffer *lpIndexBuffer, AEINT32 nIndexCount, AEINT32 nUsageFlag, AEINT32 nAdditionalBindFlag );
	
	/// \brief Ritorna l'IndexBuffer della Mesh.
	/// \return Un oggetto di tipo AEIndexBuffer contenente l'IndexBuffer.
	AE_FORCEINLINE AEIndexBuffer *GetIndexBuffer( void );
	
	/// \brief Ritorna il formato dell'IndexBuffer.
	/// \return Un valore di tipo AEIndexFormat che pu&ograve; essere \b AEINDEXFORMAT_16
	/// \b AEINDEXFORMAT_32 o \b AEINDEXFORMAT_INVALID.
	AE_DLLIMPEXP AEIndexFormat GetIndexType( void ) const;
	
	/// \brief Crea un nuovo MeshBuffer che non contiene L'indexBuffer.
	/// I vertici saranno duplicati affinch&egrave; l'apparenza della Mesh sia identica.
	/// Se la Mesh non contiene indici viene ritornato il MeshBuffer originale.
	/// \return Un MeshBuffer senza indici.
	AE_DLLIMPEXP AEMeshBuffer *FlattenOutIndexBuffer( void );
	
	AE_DLLIMPEXP static AEINT32 GetCalcPrimitiveCount( AEPrimitiveType eType, AEINT32 nVertexCount, AEINT32 nIndexCount );

	AE_DLLIMPEXP void RenderBuffer( AEMatrix4f &matWorld, AEUINT32 nStart, AEUINT32 nEnd );
	AE_DLLIMPEXP void RenderBuffer( AEUINT32 nStart, AEUINT32 nEnd );

};

#include "AEMeshBuffer.inl"

#endif // _AEMESHBUFFER_H_
